package com.harmontronics.hanma.paas.paas.domain.iam.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.harmontronics.hanma.paas.paas.consts.NumberEnum;
import com.harmontronics.hanma.paas.paas.domain.hmureport.repository.persistence.HmUreportFileRepository;
import com.harmontronics.hanma.paas.paas.domain.hmureport.repository.po.HmUreportFilePO;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.UserGroupReport;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.UserGroupReportCreate;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.valueobject.HmUserGroupComponentFileds;
import com.harmontronics.hanma.paas.paas.domain.iam.entity.valueobject.HmUserGroupReportFields;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.mapper.HmUserGroupManageMapper;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmBaseModuleComponentRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmUserGroupComponentRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmUserGroupReportRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.persistence.HmUserGroupRepository;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmBaseModuleComponentPO;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupComponentPO;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupPO;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.UserGroupTree;

import java.util.ArrayList;
import java.util.Optional;
import java.util.stream.Collectors;

import com.harmontronics.hanma.paas.paas.token.AppUserTokenKit;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.harmontronics.hanma.paas.paas.domain.iam.repository.mapper.HmUserGroupReportMapper;
import com.harmontronics.hanma.paas.paas.domain.iam.repository.po.HmUserGroupReportPO;
import java.util.List;

@Service("hmUserGroupReportService")
@DS("#header.App-Unique")
public class HmUserGroupReportService {

    private String prefix = "postgres:";

    @Autowired
    private HmUserGroupReportRepository hmUserGroupReportRepository;

    @Autowired
    private HmUserGroupReportMapper hmUserGroupReportMapper;

    @Autowired
    private HmUserGroupService hmUserGroupService;

    @Autowired
    private HmUserGroupComponentRepository hmUserGroupComponentRepository;

    @Autowired
    private HmBaseModuleComponentRepository hmBaseModuleComponentRepository;

    @Autowired
    private HmUserGroupRepository hmUserGroupRepository;

    @Autowired
    private HmUreportFileRepository hmUreportFileRepository;

    @Autowired
    private AppUserTokenKit appUserTokenKit;

    @Autowired
    private HmUserGroupManageMapper hmUserGroupManageMapper;




    public List<UserGroupReport> selectUserGroupReportWithGroupId(Long groupId) {
        List<UserGroupReport> reportList = hmUserGroupReportMapper
                .selectShowUserGroupReportWithGroupId(groupId, NumberEnum.ONE.getNum());
        for(UserGroupReport report :reportList){
            String fileName = report.getFileName();
            report.setPreFileName(fileName.substring(0,fileName.indexOf(".")));
        }
        return reportList;
    }

    public void create(UserGroupReportCreate reportCreate){
        List<Long> reportIds = reportCreate.getReportIds();
        List<HmUserGroupReportPO> userGroupReports = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(reportIds)) {
            Long groupId = reportCreate.getGroupId();
            Integer type = reportCreate.getType();
            if (groupId != null && type != null) {
                List<UserGroupReport> existGroupReportList = hmUserGroupReportMapper.selectShowUserGroupReportWithGroupId(groupId, type);
                if(CollectionUtils.isNotEmpty(existGroupReportList)){
                List<Long> existReportIds = existGroupReportList.stream()
                    .map(UserGroupReport::getReportId)
                    .collect(Collectors.toList());
                }
                for (Long reportId : reportIds) {
                    if(!existGroupReportList.contains(reportId)){
                        userGroupReports.add(new HmUserGroupReportPO()
                                .setReportId(reportId)
                                .setType(type)
                                .setGroupId(groupId));
                    }

                }
            }
        }
        hmUserGroupReportRepository.saveBatch(userGroupReports);
    }


    public void removeChildGroup(Long id) {
        HmUserGroupReportPO userGroupReport = hmUserGroupReportRepository.getById(id);
        if (userGroupReport.getType() == NumberEnum.ONE.getNum()) {
            // 查询所有子用户组
            List<Long> userGroupIdList = hmUserGroupService
                    .selectChildIdWithParentId(userGroupReport.getGroupId());
            if (CollectionUtils.isNotEmpty(userGroupIdList)) {
                hmUserGroupReportRepository.remove(new QueryWrapper<HmUserGroupReportPO>()
                        .in(HmUserGroupReportFields.GROUP_ID, userGroupIdList));
            }
        }
    }

    public void removeById(Long id){
        hmUserGroupReportRepository.removeById(id);
    }


    public void deleteWithGroupComponentId(Long groupComponentId) {
        HmUserGroupComponentPO groupComponent = deleteGroupComponent(groupComponentId);

        // 处理当前节点对应的子节点
        deleteChildComponent(groupComponent.getUserGroupId(), groupComponent.getComponentId());
    }

    private HmUserGroupComponentPO deleteGroupComponent(Long groupComponentId) {
        HmUserGroupComponentPO groupComponent = hmUserGroupComponentRepository.getById(groupComponentId);
        deleteRangeWithComponentId(groupComponent);

        // 查询出可管理范围 及 维保范围的组件， 进行删除
        /**
         if (groupComponent.getType() != NumberEnum.THREE.getNum()) {
         deleteOtherRange(groupComponent);
         }*/

        // 如果删除的是可见范围的组件，则需要删除 可管理及维保的组件
        /**
         if (groupComponent.getType() == NumberEnum.ONE.getNum()) {
         deleteComponentByTypeOne(groupComponent.getComponentId(), groupComponent.getUserGroupId());
         }*/
        return groupComponent;
    }

    private void deleteRangeWithComponentId(HmUserGroupComponentPO groupComponent) {
        // 查询出 是什么组件
        HmBaseModuleComponentPO moduleComponent = hmBaseModuleComponentRepository.getById(groupComponent.getComponentId());
        if (moduleComponent != null && moduleComponent.getName() != null) {
            String name = moduleComponent.getName();

            switch (name) {
                case "ReportVisibilityRange":
                case "ReportOperableRange":
                    hmUserGroupReportRepository.remove(
                            new UpdateWrapper<HmUserGroupReportPO>()
                                    .eq(HmUserGroupReportFields.GROUP_ID, groupComponent.getUserGroupId())
                                    .eq(HmUserGroupComponentFileds.TYPE, groupComponent.getType()));
                    break;
                default:
                    break;
            }
        }
    }

    private void deleteChildComponent(Long userGroupId, Long componentId) {
        // 查询当前用户组的所有子节点
        List<Long> userGroupIdList = hmUserGroupService.selectChildIdWithParentId(userGroupId);
        if (CollectionUtils.isNotEmpty(userGroupIdList)) {
            List<HmUserGroupComponentPO> componentList = hmUserGroupComponentRepository.list(
                    new QueryWrapper<HmUserGroupComponentPO>()
                            .in(HmUserGroupComponentFileds.USER_GROUP_ID, userGroupIdList)
                            .eq(HmUserGroupComponentFileds.COMPONENT_ID, componentId));
            componentList.forEach(ct -> {
                deleteGroupComponent(ct.getId());
                hmUserGroupComponentRepository.removeById(ct.getId());
            });
        }
    }

    public List<UserGroupReport> selectList(Long groupId){
        List<UserGroupReport> groupReportList = new ArrayList<>();
        HmUserGroupPO hmUSerGroupPO = hmUserGroupRepository.getById(groupId);
        Long tmpId = hmUSerGroupPO.getParentId();
        HmUserGroupPO groupParent = hmUserGroupRepository.getById(tmpId);

        if(Optional.ofNullable(groupParent).isPresent()){
            Long parentId = groupParent.getParentId();
            if(parentId == null){
                List<HmUreportFilePO> reportFileList = hmUreportFileRepository.list();
                for(HmUreportFilePO filePO: reportFileList){
                    UserGroupReport userGroupReport = new UserGroupReport();
                    userGroupReport.setReportId(filePO.getId());
                    userGroupReport.setFileName(filePO.getFileName());
                    groupReportList.add(userGroupReport);
                }
            }else{
                groupReportList = hmUserGroupReportMapper
                        .selectShowUserGroupReportWithGroupId(groupParent.getId(), NumberEnum.ONE.getNum());
            }
            for(UserGroupReport report:groupReportList){
                String fileName = report.getFileName();
                report.setPreFileName(fileName.substring(0,fileName.indexOf(".")));
                report.setFileName(prefix + fileName);
            }
        }
        return groupReportList;
    }

    public List<UserGroupReport> selectByUser(){
        Long userId = appUserTokenKit.getId();
        List<Long> groupIdList = hmUserGroupManageMapper.selectGroupIdsWithUserId(userId);
        if(CollectionUtils.isEmpty(groupIdList)){
            return null;
        }
        List<UserGroupReport> groupReportList = hmUserGroupReportMapper
                .selectShowUserGroupReportWithGroupIds(groupIdList,NumberEnum.ONE.getNum());
        for(UserGroupReport report:groupReportList){
            String fileName = report.getFileName();
            report.setPreFileName(fileName.substring(0,fileName.indexOf(".")));
            report.setFileName(prefix + fileName);
        }
        return groupReportList;

    }

}